package hos.http;

import android.text.TextUtils;
import android.util.Xml;

import org.xmlpull.v1.XmlPullParser;

import java.io.InputStream;
import java.io.StringReader;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <p>Title: HttpSoapUtils </p>
 * <p>Description:  </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @version : 1.0
 * @date : 2024-03-29 10:25
 */
public class HttpSoapUtils {


    public static Map<String, String> getHeaderSoap(Map<String, String> header, int version, String soapAction) {
        header.put("User-Agent", SoapConst.USER_AGENT);
        if (version != SoapConst.VER12) {
            header.put("SOAPAction", soapAction);
        }
        if (version == SoapConst.VER12) {
            header.put("Content-Type", HttpContentType.SOAP_XML_CHARSET_UTF_8);
        } else {
            header.put("Content-Type", HttpContentType.XML_CHARSET_UTF_8);
        }
        // Okhttp 会自动处理，这里不需要设置，如果设置的话，就不会自动处理了
//        header("Accept-Encoding", "gzip");
        return header;
    }

    public static String getDataXml(HttpBaseRequestSoap<?> request) {
        int version = request.getVersion();
        String nameSpace = request.getNameSpace();
        String methodName = request.getMethodName();
        Map<String, String> header = request.getHeaderBody();
        List<HttpParam> body = request.getData();
        String xsi;
        String xsd;
        if (version == SoapConst.VER10) {
            xsi = SoapConst.XSI1999;
            xsd = SoapConst.XSD1999;
        } else {
            xsi = SoapConst.XSI;
            xsd = SoapConst.XSD;
        }
        String enc;
        String env;
        String name;
        if (version < SoapConst.VER12) {
            enc = SoapConst.ENC;
            env = SoapConst.ENV;
            name = SoapConst.soap12;
        } else {
            enc = SoapConst.ENC2003;
            env = SoapConst.ENV2003;
            name = SoapConst.soap;
        }
        name = "v";
        // 开始拼接WebService
        StringBuilder builder = new StringBuilder();
        builder.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        builder.append("<").append(name).append(":Envelope")
                .append(" xmlns:i=\"")
                .append(xsi)
                .append("\" xmlns:d=\"")
                .append(xsd)
                .append("\" xmlns:c=\"")
                .append(enc)
                .append("\" xmlns:v=\"")
                .append(env)
                .append("\">");
        // 拼接内部 Header
        if (header.isEmpty()) {
            // 没有头部
            builder.append("<").append(name).append(":Header/>");
        } else {
            builder.append("<").append(name).append(":Header>");
            builder.append("<n0:SoapHeader xmlns:n0=\"")
                    .append(nameSpace)
                    .append("\"");
            Set<String> headerKeys = header.keySet();
            for (String key : headerKeys) {
                Object value = header.get(key);
                builder.append("<n0:").append(key).append(">");
                builder.append(value);
                builder.append("</n0:").append(key).append(">");
            }
            builder.append("</n0:SoapHeader>");
            builder.append("</").append(name).append(":Header>");
        }
        //  拼接 Body
        if (body.isEmpty()) {
            // 没有内容
            builder.append("<").append(name).append(":Body >");
            builder.append("<").append(methodName).append(" xmlns=\"")
                    .append(nameSpace)
                    .append("\"  id=\"o0\" c:root=\"1\" />");
            builder.append("</").append(name).append(":Body>");
        } else {
            builder.append("<").append(name).append(":Body >");
            builder.append("<").append(methodName).append(" xmlns=\"")
                    .append(nameSpace)
                    .append("\" id=\"o0\" c:root=\"1\">");
            for (HttpParam httpParam : body) {
                String key = httpParam.getKey();
                Object value = httpParam.getValue();
                if (value instanceof String) {
                    builder.append("<").append(key).append(" i:type=\"d:string\">")
                            .append(value)
                            .append("</").append(key).append(">");
                }
                if (value instanceof Integer) {
                    builder.append("<").append(key).append(" i:type=\"d:int\">")
                            .append(value)
                            .append("</").append(key).append(">");
                }
                if (value instanceof Long) {
                    builder.append("<").append(key).append(" i:type=\"d:long\">")
                            .append(value)
                            .append("</").append(key).append(">");
                }
                if (value instanceof Boolean) {
                    builder.append("<").append(key).append(" i:type=\"d:boolean\">")
                            .append(value)
                            .append("</").append(key).append(">");
                }
            }
            builder.append("</").append(methodName).append(">");
            builder.append("</").append(name).append(":Body >");
        }
        // 结束拼接
        builder.append("</").append(name).append(":Envelope >");
        return builder.toString();
    }

    /**
     * 解析XML
     *
     * @param target     解析目标
     * @param methodName 方法名
     */
    public static String parseSoapXml(String target, String methodName) {
        if (target == null || target.length() == 0 || !target.contains("<?xml")) {
            return target;
        }
        StringReader stringReader = null;
        try {
            stringReader = new StringReader(target);
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(stringReader);
            //事件类型
            int eventType = parser.getEventType();
            while (eventType != XmlPullParser.END_DOCUMENT) {
                switch (eventType) {
                    case XmlPullParser.START_DOCUMENT:
                        // 一般进行数据的初始化操作
                        break;
                    case XmlPullParser.START_TAG:
                        //获得当前节点元素的名称
                        // GetServerDateTimeResult
                        String name = parser.getName(); //获取当前节点的标记
                        if (TextUtils.equals(name, methodName + "Result")) {
                            return parser.nextText();//获得当前里的文本内容
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        // 结束标签
                        break;
                }
                eventType = parser.next();
            }
            return target;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (stringReader != null) {
                try {
                    stringReader.close();
                } catch (Exception ignored) {
                }
            }
        }
    }

    /**
     * 解析XML
     *
     * @param methodName 方法名
     */
    public static String parseSoapXml(InputStream inputStream, String methodName) {
        try {
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(inputStream, "UTF-8");
            //事件类型
            int eventType = parser.getEventType();
            while (eventType != XmlPullParser.END_DOCUMENT) {
                switch (eventType) {
                    case XmlPullParser.START_DOCUMENT:
                        // 一般进行数据的初始化操作
                        break;
                    case XmlPullParser.START_TAG:
                        //获得当前节点元素的名称
                        // GetServerDateTimeResult
                        String name = parser.getName(); //获取当前节点的标记
                        if (TextUtils.equals(name, methodName + "Result")) {
                            return parser.nextText();//获得当前里的文本内容
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        // 结束标签
                        break;
                }
                eventType = parser.next();
            }
            // 没有找到数据
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception ignored) {
                }
            }
        }
    }

}
